<?php

// +----------------------------------------------------------------------
// | EasyAdmin
// +----------------------------------------------------------------------
// | PHP交流群: 763822524
// +----------------------------------------------------------------------
// | 开源协议  https://mit-license.org 
// +----------------------------------------------------------------------
// | github开源项目：https://github.com/zhongshaofa/EasyAdmin
// +----------------------------------------------------------------------


namespace app\common\controller;

use app\admin\model\SystemAdmin;
use app\admin\service\SystemLogService;
use app\BaseController;
use app\admin\service\AuthService;
use think\facade\Db;

/**
 * Class AdminController
 * @package app\common\controller
 */
class AdminController extends BaseController
{

    use \app\common\traits\JumpTrait;

    protected $admin_id = null;
    protected $admin_name = null;
    protected $adminInfo = [];

    /**
     * 初始化方法
     */
    protected function initialize()
    {
        parent::initialize();
        $this->checkAuth();
        $this->saveSystemLog();
    }

    /**
     * 模板变量赋值
     * @param string|array $name 模板变量
     * @param mixed $value 变量值
     * @return mixed
     */
    public function assign($name, $value = null)
    {
        return $this->app->view->assign($name, $value);
    }

    /**
     * 解析和获取模板内容 用于输出
     * @param string $template
     * @param array $vars
     * @return mixed
     */
    public function fetch($template = '', $vars = [])
    {
        return $this->app->view->fetch($template, $vars);
    }

    /**
     * 重写验证规则
     * @param array $data
     * @param array|string $validate
     * @param array $message
     * @param bool $batch
     * @return array|bool|string|true
     */
    public function validate(array $data, $validate, array $message = [], bool $batch = false)
    {
        try {
            parent::validate($data, $validate, $message, $batch);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        return true;
    }

    /**
     * 检测权限
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function checkAuth(){
        $adminConfig = config('admin');
        $token  = str_replace('Bearer ', '', (string)request()->header('authorization'));
        $token = $token ?: input('access_token');
        $adminDb = new SystemAdmin();
        if ($token) {
            $adminInfo = $adminDb->where('access_token',$token)->where('status', 1)->find();
            if ($adminInfo) {
                $this->admin_id = $adminInfo['id'];
                $this->admin_name = $adminInfo['username'];
                $this->adminInfo = $adminInfo;
            }
        }

        $authService = app(AuthService::class, ['adminId' => $this->admin_id, 'authIds'=> $this->adminInfo['auth_ids']??'']);
        $currentNode = $authService->getCurrentNode();
        $currentController = parse_name(app()->request->controller());

        // 验证登录
        if (!in_array($currentController, $adminConfig['no_login_controller']) &&
            !in_array($currentNode, $adminConfig['no_login_node'])) {
            empty($this->adminInfo) && $this->result([], 301, '请先登录后台');

            // 判断是否登录过期
            if ($this->adminInfo['token_expire_time'] != 0 && time() > $this->adminInfo['token_expire_time']) {
                $this->result([], 301, '登录已过期，请重新登录');
            }
        }

        // 验证权限
        if (!in_array($currentController, $adminConfig['no_auth_controller']) &&
            !in_array($currentNode, $adminConfig['no_auth_node'])) {
            $check = $authService->checkNode($currentNode);
            !$check && $this->error('无权限访问');
        }
    }

    /**
     * 敏感信息字段，日志记录时需要加密
     * @var array
     */
    protected $sensitiveParams = [
        'password',
    ];

    /**
     * 记得系统操作日志
     */
    public function saveSystemLog() {
        $params = request()->post();
        foreach ($params as $key => $val) {
            in_array($key, $this->sensitiveParams) && $params[$key] = "***********";
        }
        $url = request()->url();

        $data = [
            'admin_name'  => (string)$this->admin_name,
            'url'         => $url,
            'ip'          => request()->ip(),
            'content'     => json_encode($params, JSON_UNESCAPED_UNICODE),
        ];
        SystemLogService::instance()->save($data);
    }
}